#include "lrcpage.h"
#include "ui_lrcpage.h"
#include <QPushButton>
#include <QFile>
#include <QDebug>

LrcPage::LrcPage(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::LrcPage)
{
    ui->setupUi(this);

    //设置歌词页面窗口无标题栏
    this->setWindowFlag(Qt::FramelessWindowHint);

    //初始化上移动画对象 与lrc歌词界面相互关联，动画是一个矩形，放到对象树上去
    animal=new QPropertyAnimation(this,"geometry",this);
    //设置动画周期500ms
    animal->setDuration(500);
    //设置动画起始帧
    animal->setStartValue(QRect(10,10,width(),height()));
    //设置动画结束帧
    animal->setEndValue(QRect(10,10+height(),width(),height()));
    //不设置动画次数，默认就是一次

    //点击下拉按钮关联clicked信号和槽函数
    connect(ui->hideBtn,&QPushButton::clicked,this,[=](){
        //启动下移动画效果
        animal->start();
    });

    //当动画结束之后，需要将窗口隐藏起来
    connect(animal,&QPropertyAnimation::finished,this,[=](){
        //将lrc歌词窗口隐藏起来
        this->hide();
    });

    //设置隐藏此lrc歌词页面按钮的图标
    ui->hideBtn->setIcon(QIcon(":/images/xiala.png"));

    //初始情况下，应该显示没有当前暂无歌词
    showLrcWordLine(-1);
}

LrcPage::~LrcPage()
{
    delete ui;
}
//对lrc歌词文件进行解析
bool LrcPage::parseLrcFile(const QString &lrcFilePath)
{
    //1、构造文件对象
    QFile file(lrcFilePath);
    //将上一首歌的lrc歌词清空
    lrcWordLines.clear();
    //2、打开lrc歌词文件，以只读方式
    if(file.open(QIODevice::ReadOnly)==false)
    {
        //打开lrc歌词文件失败
        qDebug()<<"打开lrc文件:"<<lrcFilePath<<" 失败";
        return false;
    }
    //打开lrc歌词文件成功
    //一次性读取一行lrc歌词,如果没有读到lrc歌词文件末尾，就继续读
    while(file.atEnd()==false)
    {
        //读取一行信息
        QString lrclineWord=file.readLine(1024);
        //解析歌词
        //[0:17.94]xxxxxxxxxxx
        //[0:33.600.00]xxxxxxxxxxxxxxxxx
        //1、先解析出时间和歌词的字符串文本，按照]字符来进行分割
        //初始化起始位置和最终位置的下标
        int start=0,end=0;
        //先利用]字符将歌词时间和歌词内容进行分离
        //寻找]字符的下标，从start下标开始
        end=lrclineWord.indexOf(']',start);
        //获取歌词时间和歌词文本 进行截取即可
        QString lrcTime=lrclineWord.mid(start,end-start+1);
        QString lrcWord=lrclineWord.mid(end+1,lrclineWord.size()-end-1-1);
        //2、在时间中解析出分:秒.毫秒
        //[0:33.600.00] [0:17.94]
        //解析分
        qint64 lineTime=0; //时间总毫秒数
        start=1;
        end=lrcTime.indexOf(':',start);//获取下标
        lineTime+=lrcTime.mid(start,end-start).toInt()*60*1000;//解析分 并将其转化为毫秒
        //解析秒
        start=end+1;
        end=lrcTime.indexOf('.',start);
        lineTime+=lrcTime.mid(start,end-start).toInt()*1000;//解析秒 并将其转化为毫秒
        //解析毫秒
        start=end+1;
        end=lrcTime.indexOf('.',start);
        lineTime+=lrcTime.mid(start,end-start).toInt();//解析毫秒

        //3、将该行进行保存 将一行歌词信息管理起来
        lrcWordLines.push_back(LrcWordLine(lineTime,lrcWord));
    }
    //解析完毕
    //测试解析的结果
    for(auto e : lrcWordLines)
    {
        qDebug()<<e.lrcTime<<":"<<e.lrcText;
    }

    return true;
}
//在歌词界面同步显示歌词 根据time来找到要显示的行歌词对象的歌词文本信息进行显示
void LrcPage::showLrcWordLine(qint64 time)
{
    //1、根据当前所唱的歌曲的时间time来获取当前所倡的歌曲在QVector中的索引
    int index=getLrcWordLineIndex(time);

    //2、更新当前行的前三行 当前播放行 后三行
    if(index==-1) //如果index下标不正确，显示提示信息
    {
        ui->line1->setText("");
        ui->line2->setText("");
        ui->line3->setText("");
        ui->lineCenter->setText("当前歌曲暂无歌词");
        ui->line4->setText("");
        ui->line5->setText("");
        ui->line6->setText("");
    }
    else
    {
        ui->line1->setText(getLrcWordByIndex(index-3));
        ui->line2->setText(getLrcWordByIndex(index-2));
        ui->line3->setText(getLrcWordByIndex(index-1));
        ui->lineCenter->setText(getLrcWordByIndex(index));
        ui->line4->setText(getLrcWordByIndex(index+1));
        ui->line5->setText(getLrcWordByIndex(index+2));
        ui->line6->setText(getLrcWordByIndex(index+3));
    }
}
//获取当前行在此LrcWord中的索引-根据时间来进行获取
int LrcPage::getLrcWordLineIndex(qint64 time)
{
    //将time和QVector中保存的LrcWordLine中的time进行对比
    //如果当前歌曲没有lrc歌词文件，返回-1即可
    if(lrcWordLines.isEmpty()==true)
    {
        return -1;
    }
    //如果time比第一行歌词时间都小，就返回0即可
    if(time<=lrcWordLines[0].lrcTime)
    {
        return 0;
    }
    //拿着time在QVector中保存的LrcWordLine中寻找匹配的LrcWordLines下标
    for(int i=1;i<lrcWordLines.size();i++)
    {
        if(time>=lrcWordLines[i-1].lrcTime && time<lrcWordLines[i].lrcTime)
        {
            //第i-1行还没有播放完
            return i-1;
        }
    }
    //最后一行唱完之后，歌曲结束，但是还有收尾音乐。返回此歌词的最后一行下标，让歌词界面显示最后一行歌词
    return lrcWordLines.size()-1;
}
//获取此index下标对应的lrcWordLines中的歌词信息
QString LrcPage::getLrcWordByIndex(int index)
{
    //如果index下标不正确 或者 下标超过了歌词条数
    if(index<0 || index>=lrcWordLines.size())
    {
        //返回空串即可
        return "";
    }
    //有歌词 返回对应的歌词即可
    return lrcWordLines[index].lrcText;
}
